# 用户注册视图的序列化器类
import re

from rest_framework import serializers
from users.models import User
from django_redis import get_redis_connection

class UserSerializers(serializers.ModelSerializer):
    """用户序列化器类"""
    password2 = serializers.CharField(label="确认密码", write_only=True)

    sms_code = serializers.CharField(label='短信验证码',write_only=True)

    allow = serializers.CharField(label='同意协议',write_only=True)

    token = serializers.CharField(label='JWT token',read_only=True )

    class Meta:
        model = User
        fields = ('id', 'username', 'mobile', 'password', 'password2', 'sms_code', 'allow', 'token')

        # 补充验证
        extra_kwargs = {
            'username':{
                'min_length':5,
                'max_length':20,
                'error_messages':{
                    'min_length':'最小长度为5',
                    'max_length':'最大长度为20'
                }

            },
            'password':{
                'write_only':True,
                'min_length':8,
                'max_length':20,
                'error_messages':{
                    'min_length':'最小长度为8',
                    'max_length':'最大长度为20'
                }
            }
        }

    # 手机号格式:手机号格式是否注册,是否同意协议,两次密码是否一致,短信验证码是否正确
    def validata_mobile(self,value):
        """针对mobile字段的内容进行补充验证"""
        # 手机号格式
        if not re.match(r'^1[3-9]\d{9}$',value):
            raise serializers.ValidationError('手机号格式不正确')

        # 手机号是否注册
        count = User.objects.filter(mobile=value).count()

        if count !=0:
            raise serializers.ValidationError('手机号已注册')

        return value

    def validate_data(self,value):
        """针对allow字段内容进行补充验证"""
        if value != 'True':
            raise serializers.ValidationError('请同意协议')

        return value

    def validate(self, attrs):
        """

        :param attrs: 字典,创建序列化器对象时,传入data数据
        """
        password = attrs['password']
        password2 = attrs['password2']

        if password != password2:
            raise serializers.ValidationError('两次密码不一致')

        # 短信验证码是否正确
        # 从redis中获取保存的验证码,链接到redis数据库
        redis_conn = get_redis_connection("verify_codes")

        # 获取手机号
        mobile = attrs['mobile']

        # 获取验证码
        real_sms_code = redis_conn.get('sms_%s' % mobile) # byte  存到redis中的数据都是bytes

        if real_sms_code is None:
            raise serializers.ValidationError('短信验证码已过期')

        # 获取客户端传递的验证码内容
        sms_code = attrs['sms_code'] # str

        # 对比验证码
        if real_sms_code.decode() !=sms_code:
            raise serializers.ValidationError('短信验证码错误')

        return attrs

        # 创建新用户
    def create(self, validated_data):
        """
        validated_data :校验之后的字典数据
        :param validated_data:
        :return:
        """
        # 清除无用的数据
        del validated_data['password2']
        del validated_data['sms_code']
        del validated_data['allow']

        # 创建新用户
        user = User.objects.create_user(**validated_data)

        # 生成一个 jwt token 保存用户数据身份信息
        from rest_framework_jwt.settings import api_settings

        # 生成载荷的内容
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        # 生成jwt token
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        # 给user对象动态增加属性token,保存jwt token数据
        user.token = token

        # 返回user
        return user




